#!/usr/bin/env python
# -*- coding: utf-8 -*-
import timeit
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.preprocessing import PolynomialFeatures
from sklearn import cross_validation
from sknn.mlp import Regressor, Layer
from numpy import array

arr_X = []
arr_y = []

def load_data(input_file, X_size, y_index):
    global arr_X, arr_y
    
    with open(input_file, 'r') as f:
        for line in f:
            arr = [int(i) for i in line.strip().split('\t')]
            arr_X.append(arr[:X_size])
            arr_y.append(arr[y_index])
    f.close()
    print 'len(arr_X[]): %d, len(arr_y[]): %d' % (len(arr_X), len(arr_y))
    
def load_data_by_type(input_file, X_size, y_index, type):
    global arr_X, arr_y
    
    with open(input_file, 'r') as f:
        for line in f:
            arr = [int(i) for i in line.strip().split('\t')]
            if arr[1] == type:
                arr_X.append(arr[:X_size])
                arr_y.append(arr[y_index])
    f.close()
    print 'len(arr_X[]): %d, len(arr_y[]): %d' % (len(arr_X), len(arr_y))

def do_mlr(test_size):#muliple linear regression
    global arr_X, arr_y
    X = arr_X[:test_size]
    y = arr_y[:test_size]
    print 'len(X[]): %d, len(y[]): %d' % (len(X), len(y))
    model = LinearRegression()
    model.fit(X, y)
    X_test = arr_X[test_size:]
    y_test = arr_y[test_size:]
    print 'len(X_test[]): %d, len(y_test[]): %d' % (len(X_test), len(y_test))
    predictions = model.predict(X_test)
    for i, prediction in enumerate(predictions):
        print 'Predicted: %s, Target: %s' % (prediction, y_test[i])
    print 'R-squared: %.2f' % model.score(X_test, y_test)
    

def do_pr(test_size):#polynomial regression
    global arr_X, arr_y
    X_train = arr_X[:test_size]
    y_train = arr_y[:test_size]
    print 'len(X[]): %d, len(y[]): %d' % (len(X_train), len(y_train))
    X_test = arr_X[test_size:]
    y_test = arr_y[test_size:]   
    
    regressor = LinearRegression()
    regressor.fit(X_train, y_train)
    
    quadratic_featurizer = PolynomialFeatures(degree=8)
    X_train_quadratic = quadratic_featurizer.fit_transform(X_train)
    X_test_quadratic = quadratic_featurizer.fit_transform(X_test)
    regressor_quadratic = LinearRegression()
    regressor_quadratic.fit(X_train_quadratic, y_train)
    predictions = regressor_quadratic.predict(X_test_quadratic)
#     for i, prediction in enumerate(predictions):
#         print 'Predicted: %s, Target: %s' % (prediction, y_test[i])
#     print 'R-squared: %.2f' % regressor_quadratic.score(X_test_quadratic, y_test)
    get_score(predictions, y_test)
#     print X_train
#     print X_train_quadratic
#     print X_test
#     print X_test_quadratic
#     print 'Simple linear regression r-squared', regressor.score(X_test, y_test)
#     print 'Quadratic regression r-squared', regressor_quadratic.score(X_test_quadratic, y_test)

def do_nnr(test_size):#neural network regression
    global arr_X, arr_y
    X = arr_X[:test_size]
    y = arr_y[:test_size]
    print 'len(X[]): %d, len(y[]): %d' % (len(X), len(y))
    X_test = arr_X[test_size:]
    y_test = arr_y[test_size:]
    print 'len(X_test[]): %d, len(y_test[]): %d' % (len(X_test), len(y_test))
    
    nn = Regressor(
        layers=[
            Layer("Rectifier", units=6),
            Layer("Linear")],
        learning_rate=0.00000001,
        n_iter=20)
    
    
    nn.fit(array(X), array(y))
    predictions = nn.predict(array(X_test))
    
    get_score(predictions, y_test)
#     print 'R-squared: %.5f' % nn.score(X_test, y_test)
#     print cross_validation.cross_val_score(nn, X, y, cv=10)

def do_dtr(test_size):#decision tree regression
    global arr_X, arr_y
    X = arr_X[:test_size]
    y = arr_y[:test_size]
    print 'len(X[]): %d, len(y[]): %d' % (len(X), len(y))
    X_test = arr_X[test_size:]
    y_test = arr_y[test_size:]
    print 'len(X_test[]): %d, len(y_test[]): %d' % (len(X_test), len(y_test))
    
    # Fit regression model
    regr_1 = DecisionTreeRegressor(max_depth=6)
    regr_2 = DecisionTreeRegressor(max_depth=4)
    regr_1.fit(X, y)
    regr_2.fit(X, y)
    
    # Predict
    y_1 = regr_1.predict(X_test)
    y_2 = regr_2.predict(X_test)
    
    get_score(y_1, y_test)
    print 'R-squared: %.5f' % regr_1.score(X_test, y_test)
    get_score(y_2, y_test)
    print 'R-squared: %.5f' % regr_2.score(X_test, y_test)
    
    print cross_validation.cross_val_score(regr_1, X, y, cv=10)
    print cross_validation.cross_val_score(regr_2, X, y, cv=10)
 
def get_score(predictions, y_test):
    score = 0.
    for i, prediction in enumerate(predictions):
        print 'Predicted: %s, Target: %s' % (prediction, y_test[i])
        score += abs(prediction-y_test[i]) * 1. / y_test[i]
    print 'mean-deviation: %.5f' % (score/len(y_test))

def main():
    line = 10
    
    #20140801    5    0    1    36    5    26    44256
    day_file = 'format/dayd.txt'
    load_data(day_file, 5, 5)
#     do_mlr(-7)
#     do_pr(-7)
#     do_dtr(-7)
    
    
    #2    4    1    36    5    26    309
#     day_type_file = '/home/ivy/git/passenger/passenger/resource/format/day_type_%d.txt' % line
#     load_data(day_type_file, 4, 6)
#     load_data_by_type(day_type_file, 4, 6, 1)
#     do_mlr(-7)
#     do_pr(-10)
    do_nnr(-10)
#     do_dtr(-10)
    
if __name__ == '__main__':
    start = timeit.default_timer()
    
    main()
    
    stop = timeit.default_timer()
    print 'run time: %.10fs' % (stop - start)
    
